﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection.Emit;
using System.Reflection;

namespace Kokomo
{
	public static class ILGeneratorExtensions
	{
		public static void EmitLoad(this ILGenerator il, object value)
		{
			ArgumentValidation.CheckNullArgument("il", il);

			if (value == null)
			{
				il.Emit(OpCodes.Ldnull);
			}
			else if (value is int)
			{
				il.Emit(OpCodes.Ldc_I4, (int)value);
			}
			else if (value is short)
			{
				il.Emit(OpCodes.Ldc_I4, (int)(short)value);
				il.Emit(OpCodes.Conv_I2);
			}
			else if (value is byte)
			{
				il.Emit(OpCodes.Ldc_I4, (int)(byte)value);
				il.Emit(OpCodes.Conv_I1);
			}
			else if (value is string)
			{
				il.Emit(OpCodes.Ldstr, (string)value);
			}
			else if (value is bool)
			{
				il.Emit(OpCodes.Ldc_I4, ((bool)value) ? 1 : 0);
			}
			else
			{
				throw new ArgumentException(string.Format("Cannot load value of type {0}", value.GetType()));
			}
		}

		public static void EmitCall(this ILGenerator il, MethodInfo method)
		{
			ArgumentValidation.CheckNullArgument("il", il);
			ArgumentValidation.CheckNullArgument("method", method);

			OpCode callOpcode = (method.IsVirtual ? OpCodes.Callvirt : OpCodes.Call);
			il.Emit(callOpcode, method);
		}
	}
}
